<?php
// +----------------------------------------------------------------------+
// | Author:  Evgeny Leontev <eleontev@gmail.com>                         |
// | Copyright (c) 2005 Evgeny Leontev                                    |
// +----------------------------------------------------------------------+
// | This source file is free software; you can redistribute it and/or    |
// | modify it under the terms of the GNU Lesser General Public           |
// | License as published by the Free Software Foundation; either         |
// | version 2.1 of the License, or (at your option) any later version.   |
// |                                                                      |
// | This source file is distributed in the hope that it will be useful,  |
// | but WITHOUT ANY WARRANTY; without even the implied warranty of       |
// | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU    |
// | Lesser General Public License for more details.                      |
// +----------------------------------------------------------------------+

/**
 * PageByPage is a class used to create page by page navigation.
 * 
 * @since 20/05/2003
 * @author Evgeny Leontev <eleontev@gmail.com>
 * @access public
 */


class PageByPage {
	
	//var $form_action; 
	var $hidden; 			// values to be in get string
	var $query;
	
	var $get_name = 'bp';	// $_GET name to be in query	
	var $get_delim = '|';
	var $action_page = '';
	
	var $offset = 0;		// mysql offset
	var $limit = 10;		// mysql offset
	var $num_records;		// num records
	var $num_pages;			// num pages
	var $cur_record = 1; 	// number of record
	var $cur_page = 1;		// number of page
	var $nav;
	
	var $use_form = true;
	
	var $page_msg = 'Page';
	var $record_msg = 'Records'; 
	var $record_from_msg = 'from';
	
	var $per_page_msg = 'Records per page';
	var $per_page_name = 'records_per_page';
	var $per_page_range = array(10, 20, 40);	
	
	
	function PageByPage($limit = false, $hidden = false) {
		if($limit) { $this->limit = $limit; }
		if($hidden) { $this->_setVars($hidden); }
		
		// overwrite limit 
		if(isset($_GET[$this->per_page_name])) {
			$this->limit = $_GET[$this->per_page_name];
		}
	}
	
	
	// to use get vars in navigation 
	function _setVars($arr) {
		unset($arr[$this->get_name], $arr['submit']);
		$this->hidden = http_build_hidden($arr);
		$this->query = '&' . http_build_query($arr);
	}

	

	// using COUNT() for count, use it in $sql
	function countAll($sql, $db_obj = false){
		if(!isset($_GET[$this->get_name])) {
			
			if(is_numeric($sql)) {
				$this->num_records = $sql; // num records
				
			} else {
				
				$sql = preg_replace("#SELECT\s{1,}(.+?)\s{1,}FROM# is", 'SELECT COUNT(*) FROM', $sql);
				//echo "<pre>"; print_r($sql); echo "</pre>";
				
				if($db_obj) {
					$val = $db_obj->GetCol($sql) or die (db_error($sql));
					$this->num_records = $val[0];
				} else {
					$result = mysql_query($sql) or die (db_error($sql));
					$this->num_records = @mysql_result($result,0); // num records
				}
			}  
		}
		
		//echo "<pre>"; print_r($sql); echo "</pre>";
		return $this->_prepare();
	}
	
	
	// set sql with limit
	function setLimitSql($sql){
		$sql .= sprintf(" LIMIT %d, %d", $this->offset, $this->limit);
		return $sql;
	}
	
	
	
	// using mysql_num_rows() for count
	function countReal($sql, $db_obj = false){
		if(!isset($_GET[$this->get_name])) {
			$result = mysql_query($sql) or die (db_error());
			$this->num_records = mysql_num_rows($result);
		}	
		
		return $this->_prepare();
	}

	
	
	function _prepare() {
		
		if(!isset($_GET[$this->get_name])) {
			$this->num_pages = ceil($this->num_records/$this->limit);   //num pages
		} else {
			list($this->offset, $this->num_records, $this->num_pages, $this->cur_record, $this->cur_page) = explode($this->get_delim, urldecode($_GET[$this->get_name]));
		}
		
		$sql_limit['offset'] = $this->offset;
		$sql_limit['limit'] = $this->limit;
		return $sql_limit;
	}
	
	
	function _pages(){
		
		if(!$this->action_page) {
			$this->action_page = $_SERVER['PHP_SELF'];
		}

		$a = sprintf('<form action="%s" name="by_page" style="margin : 0px 0px;">', $this->action_page);
		$a .= $this->page_msg . ": ";
		
		
		if($this->use_form == false) {
			
			$a .= $this->cur_page . ' ';
			$a .=  $this->record_from_msg . ' ' . $this->num_pages;
		
		} elseif($this->num_pages > 1){
			
			$a .=  sprintf('<select name="%s" style="padding: 0px; width: 45; font: 10px;" onchange="document.by_page.submit();">', $this->get_name);
			
			for($i=1;$i<=$this->num_pages;$i++) {
				if($this->cur_page == $i) {
					$a .= '<option value="" selected="selected">'.$i.'</option>';
				} else {
					$bp = $i*$this->limit-$this->limit . $this->get_delim;
					$bp .= $this->num_records . $this->get_delim;
					$bp .= $this->num_pages . $this->get_delim;
					$bp .= ($i*$this->limit-$this->limit+1) . $this->get_delim;
					$bp .= $i;
					
					$a .= '<option value="'.$bp.'">'.$i.'</option>';
				}
			}
			$a .= '</select> ';
			$a .=  $this->record_from_msg . ' ' . $this->num_pages;
		
		} else {
			$a .= 1;
		}
		
		
		$sign = (strpos($this->action_page, '?') !== false) ? '&' : '?';
		
		// print previos arows (<<) 	
		if($this->num_pages > 1 && $this->cur_page != 1){
			
			$bp = $this->offset-$this->limit . $this->get_delim; 			// offset
			$bp .= $this->num_records . $this->get_delim; 	//
			$bp .= $this->num_pages . $this->get_delim; 
			$bp .= $this->cur_record-$this->limit . $this->get_delim; 	// cur record when numerate records
			$bp .= $this->cur_page-1;					// cur page
			
			$a .= '&nbsp;&nbsp;<a href="'.$this->action_page.$sign.$this->get_name.'='.$bp.$this->query.'" title="previos"><b>&laquo;&laquo;</b></a>';
		}
		
			
		// print next arrows (>>) 
		if($this->num_pages > $this->cur_page){
			
			$bp = $this->limit*$this->cur_page . $this->get_delim;
			$bp .= $this->num_records . $this->get_delim;
			$bp .= $this->num_pages . $this->get_delim;
			$bp .= ($this->cur_page*$this->limit+1) . $this->get_delim;
			$bp .= $this->cur_page+1;
			
			$a .= '&nbsp;&nbsp;<a href="'.$this->action_page.$sign.$this->get_name.'='.$bp.$this->query.'" title="next"><b>&raquo;&raquo;</b></a>';
		}
		
		$a .= $this->hidden; // hidden fields
		$a .= '</form>';	
		return $a;
	}
	
	
	function _records(){
		
		$n = $this->limit*$this->cur_page;
		if($n > $this->num_records){
			$b =  ($n - $this->num_records);
			$n = ($n - $b);
			}
	
		return $this->record_msg . ": ".($this->offset+1)."-".$n." ".$this->record_from_msg." ".$this->num_records;
	}
	
	// set msg, we should create 3 msg
	// for example: setMsg(Pages, Records, from)
	function setMsg($msg) {
		if(!is_array($msg)) { $msg = func_get_args(); }
		
		$this->page_msg = $msg[0];
		$this->record_msg = $msg[1]; 
		$this->record_from_msg = $msg[2];
	}
	
	
	function setPerPageMsg($msg) {
		$this->per_page_msg = $msg;
	}
	
	
	function setPerPageRange($arr) {
		$this->per_page_range = array();
		foreach($arr as $v) {
			$this->per_page_range[$v] = $v;
		}
	}
	
	
	// to print page by page line
	function navigate($more_fields = false){
		
		if($more_fields !== false) {
			require_once ('HTML/FormSelect.php');
			
			$this->setPerPageRange($this->per_page_range);
			
			$select = new FormSelect();
			$select->setFormMethod($_GET);
			$select->setFormName('per_page_form');
			$select->setSelectWidth(50);
			$select->setOnChangeSubmit();
			
			$select->setSelectName($this->per_page_name);
			$select->setRange($this->per_page_range);
			
			$sel_html = '<form action="" style="margin: 0px;">';
			$limit = (isset($_GET[$this->per_page_name])) ? $_GET[$this->per_page_name] : $this->limit;
			$sel_html .= $select->select($limit);
			
			$vars = $_GET;
			unset($vars[$this->per_page_name]);
			$sel_html .= http_build_hidden($vars);
			
			$sel_html .= '</form>';
			
			$sel_html = '<td style="white-space: nowrap;">&nbsp;' . $this->per_page_msg . ':</td>
				         <td>'.$sel_html.'</td>';
			
		} else {
			$sel_html = '';
		}		

		$html = '<table cellpadding="4" cellspacing="0" border="0" width="100%">
		<tr bgcolor="#e7e7e7">
			
			<td width="100%">'.$this->_records().'</td>
			<td nowrap align="right" style="padding-right: 15px;">'.$this->_pages().'</td>
			<td bgcolor="#ffffff" style="padding: 1px;"></td>
			
			' . $sel_html . '
			
		</tr>
		</table>';
		
		return $html;
	}
	
	
	function _pages1() {
		
		if(!$this->action_page) {
			$this->action_page = $_SERVER['PHP_SELF'];
		}

		$sign = (strpos($this->action_page, '?') !== false) ? '&' : '?';
		$a = '';
		//$a .= $this->page_msg . ": ";
		
		
		// print previos arows (<<) 	
		if($this->num_pages > 1 && $this->cur_page != 1){
			
			$bp = $this->offset-$this->limit . $this->get_delim; 			// offset
			$bp .= $this->num_records . $this->get_delim; 	//
			$bp .= $this->num_pages . $this->get_delim; 
			$bp .= $this->cur_record-$this->limit . $this->get_delim; 	// cur record when numerate records
			$bp .= $this->cur_page-1;					// cur page
			
			$a .= '&nbsp;&nbsp;<a href="'.$this->action_page.$sign.$this->get_name.'='.$bp.$this->query.'" title="Previous"><b>&laquo;&laquo;</b></a>';
		}
		
			
		// print next arrows (>>) 
		if($this->num_pages > $this->cur_page){
			
			$bp = $this->limit*$this->cur_page . $this->get_delim;
			$bp .= $this->num_records . $this->get_delim;
			$bp .= $this->num_pages . $this->get_delim;
			$bp .= ($this->cur_page*$this->limit+1) . $this->get_delim;
			$bp .= $this->cur_page+1;
			
			$a .= '&nbsp;&nbsp;<a href="'.$this->action_page.$sign.$this->get_name.'='.$bp.$this->query.'" title="next"><b>&raquo;&raquo;</b></a>';
		}
		
		return $a;
	}
	
	
	function shortNavigate() {
		return sprintf('%s&nbsp;&nbsp;%s', $this->_records(), $this->_pages1());
	}
}

// Showing 1 to 10 of 177     	< Previous  	    	Next >  	

/*
$bp = new PageByPage(10, $_GET);
$bp->countAll(15);

echo $bp->shortNavigate();
echo "<pre>"; print_r($bp); echo "</pre>";
*/
?>